﻿using AutoMapper;
using MediatR;
using ProductionManagement.Application.Command.ProductionPlanCommand;
using ProductionManagement.Domain.ProductionDomain;
using ProductionManagement.Infrstructre.lnterface;
using SqlSugar;

namespace ProductionManagement.Application.CommandHandler.ProductionPlanCommandHandler
{
    /// <summary>
    /// 添加生产计划命令处理器
    /// </summary>
    public class ProductionPlanCreateCommandHandler : IRequestHandler<ProductionPlanCreateCommand, int>
    {
        private readonly IProductionPlanRepository _productionPlanRep;
        private readonly IProductionProductRepository _productionProductRep;
        private readonly IPreProducsRepository _preProducsRep;
        private readonly IPreProductionRepository _preProductionRep;
        private readonly ISqlSugarClient _db;
        private readonly IMapper _mapper;

        public ProductionPlanCreateCommandHandler(IProductionPlanRepository productionPlanRep, IProductionProductRepository productionProductRep, ISqlSugarClient db, IMapper mapper, IPreProducsRepository preProducsRep, IPreProductionRepository preProductionRep)
        {
            this._productionPlanRep = productionPlanRep;
            this._productionProductRep = productionProductRep;
            this._db = db;
            this._mapper = mapper;
            this._preProducsRep = preProducsRep;
            this._preProductionRep = preProductionRep;
        }

        public async Task<int> Handle(ProductionPlanCreateCommand request, CancellationToken cancellationToken)
        {
            // 开启事务
            _db.Ado.BeginTran();
            try
            {
                // 将请求数据映射到实体
                var purchaseContract = _mapper.Map<ProductionPlan>(request.addDto);

                // 插入预生产计划
                int contractId = await _productionPlanRep.AddAsync(purchaseContract);

                
                // 假设需要插入相关的预生产产品信息
                foreach (var item in request.addDto.adddtos)
                {
                    ProductionProduct detail = new ProductionProduct
                    {
                        PPDocumentNumber = purchaseContract.PPDocumentNumber,
                        ProductId = item.ProductId,
                        PNumber = item.PNumber,
                        PName = item.PName,
                        PSpec = item.PSpec,
                        PUnit = item.PUnit,
                        PPNum = item.PPNum,
                        MSubject = item.MSubject,
                        PPAppStartDate = item.PPAppStartDate,
                        PPAppEndDate = item.PPAppEndDate,
                        PPReleDate = item.PPReleDate,
                        PProuctSmark = item.PProuctSmark,
                        AddName = purchaseContract.AddName,
                        AddTime = purchaseContract.AddTime,
                        Office_Id = purchaseContract.Office_Id,
                        User_Id = purchaseContract.User_Id
                    };
                    //查询到需要改的预生产计划
                    var hh = (await _preProductionRep.GetAll()).Where(t => t.PreProductionId == purchaseContract.PreProductionPlanId).ToList();
                    // 更新预生产计划的状态
                    foreach (var items in hh)
                    {
                        if (items.PPGeneratedNum == purchaseContract.PPTotalQuantity)
                        {
                            if (item.PPNum >= items.PPGeneratedNum)
                            {
                                items.PPState = 3;
                            }
                        }
                        else
                        {
                            items.PPState = 2;
                        }
                        items.PPGeneratedNum = item.PPNum;
                        await _preProductionRep.UpdAsync(items);
                    }
                    await _productionProductRep.AddAsync(detail);
                }

                // 提交事务
                _db.Ado.CommitTran();

                return 1;
            }
            catch (Exception ex)
            {
                // 捕获异常并回滚事务
                _db.Ado.RollbackTran();
                // 可以记录日志以便调试
                throw new Exception("事务失败，已回滚所有操作", ex);
            }
        }
    }
}
